package com.power.sifa.statistics.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.plf.common.domain.PageDataResponse;
import com.plf.common.domain.YesNo;
import com.plf.common.exception.BusinessException;
import com.plf.common.file.service.IFileService;
import com.plf.common.utils.JSONUtil;
import com.plf.core.base.model.EnumerationHelper;
import com.plf.core.base.model.Ha_attachment;
import com.plf.core.base.model.Ha_depart;
import com.plf.core.base.service.Ha_attachmentService;
import com.plf.core.base.service.impl.Ha_departServiceImpl;
import com.plf.core.base.service.impl.Ha_enumerationServiceImpl;
import com.power.sifa.aop.service.SMService;
import com.power.sifa.correction.dao.Crc_personDao;
import com.power.sifa.correction.dao.Cre_warningDao;
import com.power.sifa.correction.model.*;
import com.power.sifa.correction.model.enumeration.*;
import com.power.sifa.correction.model.pageInfo.Cre_record_gaPageInfo;
import com.power.sifa.correction.model.pageInfo.Cre_warningPageInfo;
import com.power.sifa.correction.model.pojo.vo.PhotoVO;
import com.power.sifa.correction.service.*;
import com.power.sifa.statistics.model.enumeration.AddressAdid;
import com.power.sifa.statistics.model.pageInfo.CameraPageInfo;
import com.power.sifa.statistics.model.pageInfo.CorrectCountPageInfo;
import com.power.sifa.statistics.model.pageInfo.MarkPointPageInfo;
import com.power.sifa.statistics.model.vo.*;
import com.power.sifa.statistics.service.CorrectionCountService;
import com.power.sifa.util.GeocoderUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CorrectionCountServiceImpl implements CorrectionCountService {

    private final Cre_warningService cre_warningService;

    private final Crc_personService crc_personService;

    private final Crc_personDao crcPersonDao;

    private final Cre_record_gaService cre_record_gaService;

    private final Ha_departServiceImpl ha_departService;

    private final Cre_warning_detailService cre_warning_detailService;

    private final Crw_rule_geopointService crw_rule_geopointService;

    private final Crc_cameraService crc_cameraService;

    @Resource
    private Cre_warningDao creWarningDao;

    @Resource
    private SMService smService;

    @Resource
    private Ha_attachmentService ha_attachmentService;

    /**
     * 条件查询当前的预警坐标
     *
     * @param pageInfo
     * @return
     */
    @Override
    public List<MarkPointVO> markPointList(MarkPointPageInfo pageInfo) {
        Cre_warningPageInfo cre_warningPageInfo = new Cre_warningPageInfo();
        if (StringUtils.isNotBlank(pageInfo.getStartDate()) && StringUtils.isNotBlank(pageInfo.getEndDate())) {
            cre_warningPageInfo.setF_rectime(pageInfo.getStartDate());
            cre_warningPageInfo.setF_rectime_01(pageInfo.getEndDate());
        }
        if (!CollectionUtils.isEmpty(pageInfo.getStatus())) {
            cre_warningPageInfo.setF_status(pageInfo.getStatus());
        }

        List<Integer> integerList = pageInfo.getStatus().stream()
                .map(Integer::parseInt)
                .collect(Collectors.toList());

        List<Cre_warning> warnings = creWarningDao.findListByWorkStatus(integerList);
        if (CollectionUtils.isEmpty(warnings)) {
            return Collections.emptyList();
        }
        // 针对坐标进行去重
        Map<String, Cre_warning> warningIdMap = new HashMap<>();
        warnings.stream().filter(el -> ObjectUtil.isNotNull(el.getLngcamera()) && ObjectUtil.isNotNull(el.getLatcamera())).forEach(el -> {
            warningIdMap.put(el.getLatcamera() + "," + el.getLngcamera(), el);
        });
        List<Cre_warning> distinctWarnningList = warnings.stream().filter(el -> ObjectUtil.isNotNull(el.getLngcamera()) && ObjectUtil.isNotNull(el.getLatcamera()))
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(Cre_warning::getLatcamera).thenComparing(Cre_warning::getLngcamera))),
                        ArrayList::new));

        return distinctWarnningList.stream().map(warning -> MarkPointVO.builder()
                .id(warning.getId())
                .gaid(warning.getGaid())
                .rectime(warning.getRectime())
                .lat(String.valueOf(warning.getLatcamera()))
                .lng(String.valueOf(warning.getLngcamera()))
                .build()).collect(Collectors.toList());
    }

    /**
     * 预警数据详情
     *
     * @param warningId
     * @return
     */
    @Override
    public MarkPointDetailsVO markPointDetails(String warningId) {
        return MarkPointDetailsVO.builder()
                .warning(this.getWarningDetails(warningId))
                .geopoints(this.getGeopoints(warningId))
                .build();
    }

    /**
     * 获取所有预警图片
     *
     * @return
     */
    @Override
    public List<PhotoVO> getWarningPhotoMap(Integer gaId, Integer timeScope) {
        List<Cre_record_ga> creRecordGaList = this.getCreRecordGaList(gaId, timeScope);
        if (creRecordGaList != null && creRecordGaList.size() > 0) {
            List<PhotoVO> photoList = creRecordGaList.stream()
                    .filter(creRecordGa -> creRecordGa.getPhoto() != null && creRecordGa.getFacephoto() != null)
                    .map(creRecordGa -> PhotoVO.builder()
                            .photo(ha_attachmentService.getFileUrl(creRecordGa.getPhoto()))
                            .facePhoto(ha_attachmentService.getFileUrl(creRecordGa.getFacephoto()))
                            .build())
                    .collect(Collectors.toList());

            return photoList;
        }
        return null;
    }

    /**
     * 初始化手机坐标位置
     *
     * @param cre_warning
     */
    private void initMobileAddr(Cre_warning cre_warning) {
        if (ObjectUtil.isNotNull(cre_warning) && Objects.nonNull(cre_warning.getLatmobile()) && Objects.nonNull(cre_warning.getLngmobile())) {
            String mobileAddr = String.valueOf(cre_warning.getLatmobile() + cre_warning.getLngmobile());
            cre_warning.setMobileAddr(GeocoderUtil.reverseParseAddress(mobileAddr));
        }
    }

    /**
     * 初始化司法所地址
     *
     * @param deptid
     * @return
     * @throws Exception
     */
    private String initDepartName(String deptid) throws Exception {
        Ha_depart depart = ha_departService.getById(deptid);
        if (Objects.isNull(depart)) {
            throw new BusinessException("获取司法所信息失败，当前id：" + deptid);
        }
        return depart.getName();
    }


    /**
     * 根据预警id获取大屏展示预警详情
     */
    @SneakyThrows
    private WarningDetails getWarningDetails(String warningId) {
        Cre_warning cre_warning = cre_warningService.getById(warningId);
        if (Objects.isNull(cre_warning)) {
            throw new BusinessException("获取预警信息失败，当前id：" + warningId);
        }
        cre_warning.geneText();
        initMobileAddr(cre_warning);

        String personId = cre_warning.getPerid();
        if (Objects.isNull(personId)) {
            throw new BusinessException("社区矫正人员id不能为空");
        }
        Crc_person person = crcPersonDao.findDeptById(personId);
        person.setDeptname(person.getDeptname());
        person.setAvatarUrl(person.getAvatarUrl());
        if (Objects.isNull(person)) {
            throw new BusinessException("获取社区矫正人员失败，当前id：" + personId);
        }
        person.geneText();

        String deptid = person.getDeptid();
        if (Objects.isNull(deptid)) {
            throw new BusinessException("司法所id不能为空");
        }

        try {
            cre_warning.setPername(smService.encrypt(cre_warning.getPername()));
            cre_warning.setDescribe(smService.encrypt(cre_warning.getDescribe()));
            person.setPhone(smService.encrypt(person.getPhone()));
            person.setName(smService.encrypt(person.getName()));
        } catch (Exception e) {
            throw new BusinessException("信息加密有误");
        }

//        Cre_warning warning = creWarningDao.getById(warningId);
        List<PhotoVO> photoVOList = this.getWarningPhotoMap(cre_warning.getGaid(), 100);

        NightRuleVO nightRuleVO = this.getNightRuleVO(Tp_crc_rule.NIGHTOUT, cre_warning.getGaid());

        WarningDetails details = WarningDetails.builder()
                .id(warningId).perid(personId)
                .warningInfo(cre_warning)
                .personInfo(person)
                .photoVOList(photoVOList)
                .nightRuleVO(nightRuleVO)
                .build();

        return details;
    }

    private NightRuleVO getNightRuleVO(int nightout, Integer gaid) {
        NightRuleVO nightRuleVO = this.cre_warning_detailService.getNightRuleVO(nightout, gaid);
        if (ObjectUtil.isNotNull(nightRuleVO)) {
            return nightRuleVO;
        }
        return null;
    }

    private List<PhotoVO> getPhotoList(Cre_warning creWarning, Integer timeScope) {
        if (ObjectUtil.isNull(creWarning)) {
            throw new RuntimeException("预警信息不能为空");
        }
        Date rectime = creWarning.getRectime();
        LocalDateTime localDateTime = rectime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 获取数据范围
        LocalDateTime startTime = localDateTime.plusMinutes(-timeScope.longValue());
        LocalDateTime endTime = localDateTime.plusMinutes(timeScope.intValue());
        Cre_record_gaPageInfo pageInfo = new Cre_record_gaPageInfo();
        pageInfo.setF_perid(creWarning.getPerid());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        pageInfo.setF_rectime(startTime.format(formatter));
        pageInfo.setF_rectime_01(endTime.format(formatter));
        List<PhotoVO> photoVOList = creWarningDao.getPhotoList(pageInfo);
        return photoVOList;
    }

    /**
     * 根据预警id获取地图范围坐标
     */
    private List<GeopointDetails> getGeopoints(String warningId) {

        List<Cre_warning_detail> warningDetails = cre_warning_detailService.findByWarningId(warningId);

        if (CollectionUtils.isEmpty(warningDetails)) {
            return Collections.emptyList();
        }

        List<GeopointDetails> result = new ArrayList<>();
        warningDetails.stream()
                .collect(Collectors.toMap(Cre_warning_detail::getRuleid, Function.identity(), (oldValue, newValue) -> oldValue))
                .values()
                .forEach(details -> {
                    String ruleId = details.getRuleid();
                    List<Crc_geopoint> geopoints = crw_rule_geopointService.findGeopointsByRuleId(ruleId);
                    if (!CollectionUtils.isEmpty(geopoints)) {
                        geopoints.forEach(geopoint -> {
                            List list = JSONUtil.json2List(geopoint.getGeopoints(), List.class).get(0);
                            GeopointDetails geopointDetails = GeopointDetails.builder().points(list).rule_name(details.getRulename()).geopointId(geopoint.getId()).build();
                            if (ruleId.startsWith("A")) {
                                geopointDetails.setRule_type(Tp_crc_ruleEnum.ZONE_OUT_RULE.getId());
                            } else if (ruleId.startsWith("B")) {
                                geopointDetails.setRule_type(Tp_crc_ruleEnum.ZONE_IN_RULE.getId());
                            }
                            result.add(geopointDetails);
                        });
                    }

                });
        return result;
    }


    @Override
    public List<BaseCountVO> countCorrectPersonInfo(List<String> deptIds) {
        List<Crc_person> personList = crcPersonDao.findByDeptID(deptIds);

        BaseCountVO countBase = BaseCountVO.builder().key("personTotal").name("社矫人员总数").count(0L).build();
        BaseCountVO countTypeOne = BaseCountVO.builder().key("controlTypeOne").name("一类人员").count(0L).build();
        BaseCountVO countTypeTwo = BaseCountVO.builder().key("controlTypeTwo").name("二类人员").count(0L).build();
        BaseCountVO countTypeThree = BaseCountVO.builder().key("controlTypeThree").name("三类人员").count(0L).build();
        BaseCountVO countTypeFocus = BaseCountVO.builder().key("countTypeFocus").name("重点人员").count(0L).build();

        if (CollectionUtil.isNotEmpty(personList)) {
            countBase.setCount(Long.valueOf(personList.size()));
            // 统计重点人员
            Long focusCount = personList.stream()
                    .filter(el -> ObjectUtil.isNotNull(el.getFocus()) && el.getFocus().equals(YesNo.YES))
                    .count();
            countTypeFocus.setCount(focusCount);
            // 进行分类统计
            Map<Integer, List<Crc_person>> personListGroup = personList.stream()
                    .filter(el -> ObjectUtil.isNotNull(el.getControltype()))
                    .collect(Collectors.groupingBy(Crc_person::getControltype));
            if (ObjectUtil.isNotNull(personListGroup)) {
                for (Integer key : personListGroup.keySet()) {
                    switch (key) {
                        case Tp_crc_ctrl.A:
                            countTypeOne.setCount(Long.valueOf(personListGroup.get(key).size()));
                            break;
                        case Tp_crc_ctrl.B:
                            countTypeTwo.setCount(Long.valueOf(personListGroup.get(key).size()));
                            break;
                        case Tp_crc_ctrl.C:
                            countTypeThree.setCount(Long.valueOf(personListGroup.get(key).size()));
                            break;
                    }
                }
            }
        }
        return Arrays.asList(countBase, countTypeOne, countTypeTwo, countTypeThree, countTypeFocus);
    }

    @Override
    public BaseGraphVO countCorrectCrime(List<String> deptIds) {
        BaseGraphVO result = new BaseGraphVO();
        // 查询重点人员案件类型统计人数前六的数据
        List<Map<String, Object>> personList = crcPersonDao.countTopCrimeList(deptIds);
        if (CollectionUtil.isNotEmpty(personList)) {
            // 选取top6的数据
            List<String> columnList = new ArrayList<>();
            List<Long> valueList = new ArrayList<>();

            personList.stream().forEach(el -> {
                columnList.add(el.get("crime").toString());
                valueList.add(Long.valueOf(el.get("count").toString()));
            });
            result.setColumnList(columnList);
            result.setValueList(valueList);
        }
        return result;
    }

    @Override
    public BaseGraphVO countCorrectPersonLocation(List<String> f_deptid) {
        BaseGraphVO result = new BaseGraphVO();
        List<Crc_person> personList = crc_personService.findAll();

        if (ObjectUtil.isNotNull(f_deptid) && ObjectUtil.isNotEmpty(f_deptid)) {
            personList = personList.stream()
                    .filter(el -> f_deptid.contains(el.getDeptid()))
                    .collect(Collectors.toList());
        }

        // 初始化对应的返回数据，返回对应的区县
        // 按照特定顺序排序 南昌县，进贤县，安义县，东湖区，西湖区，青云谱区，青山湖区，新建区，红谷滩区，经开区，高新区，湾里管理区

        List<String> columnList = Arrays.asList(AddressAdid.J, AddressAdid.L, AddressAdid.K, AddressAdid.A,
                AddressAdid.B, AddressAdid.C, AddressAdid.G, AddressAdid.H, AddressAdid.I, AddressAdid.F, AddressAdid.E,
                AddressAdid.D);
        List<Long> valueList = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L);

        if (CollectionUtil.isNotEmpty(personList)) {
            // 进行地区的统计
            Map<String, List<Crc_person>> personLocationMap = personList.stream().filter(el -> ObjectUtil.isNotNull(el.getAdid()))
                    .collect(Collectors.groupingBy(Crc_person::getAdid));
            if (ObjectUtil.isNotNull(personLocationMap)) {
                for (String key : personLocationMap.keySet()) {
                    for (int index = 0; index < columnList.size(); index++) {
                        if (columnList.get(index).equals(key)) {
                            valueList.set(index, personLocationMap.get(key).stream().count());
                            break;
                        } else {
                            continue;
                        }
                    }
                }
            }
            result.setColumnList(columnList);
            result.setValueList(valueList);
        }
        return result;
    }

    @Override
    public List<BaseCountVO> countWarningByTime(CorrectCountPageInfo pageInfo) {
        LocalDate nowTime = LocalDate.now();
        Date beginDate = null;
        LocalTime startTime = LocalTime.of(0, 0, 0);
        LocalTime endTime = LocalTime.of(23, 59, 59);
        Date endDate = Date.from(LocalDateTime.of(nowTime, endTime).atZone(ZoneId.systemDefault()).toInstant());
        switch (pageInfo.getQueryType()) {
            case 0:
                // 按照周查询
                LocalDate firstDayOfWeek = nowTime.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
                LocalDateTime firstDayOfWeekTime = LocalDateTime.of(firstDayOfWeek, startTime);
                beginDate = Date.from(firstDayOfWeekTime.atZone(ZoneId.systemDefault()).toInstant());
                break;
            case 1:
                // 按照月查询
                LocalDate firstDayOfMonth = nowTime.with(TemporalAdjusters.firstDayOfMonth());
                LocalDateTime firstDayOfMonthTime = LocalDateTime.of(firstDayOfMonth, startTime);
                beginDate = Date.from(firstDayOfMonthTime.atZone(ZoneId.systemDefault()).toInstant());
                break;
            case 2:
                // 按照年查询
                LocalDate firstDayOfYear = nowTime.with(TemporalAdjusters.firstDayOfYear());
                LocalDateTime firstDayOfYearTime = LocalDateTime.of(firstDayOfYear, startTime);
                beginDate = Date.from(firstDayOfYearTime.atZone(ZoneId.systemDefault()).toInstant());
                break;
        }
        // 进行条件查询 Tp_crc_warn
        BaseCountVO countCross = BaseCountVO.builder().key("cross").name("违规越界").count(0L).build();
        BaseCountVO countSeparation = BaseCountVO.builder().key("separation").name("人机分离").count(0L).build();
        BaseCountVO countLocations = BaseCountVO.builder().key("locations").name("重点场所").count(0L).build();
        BaseCountVO countLurks = BaseCountVO.builder().key("lurks").name("昼伏夜出").count(0L).build();
//        BaseCountVO countGathering = BaseCountVO.builder().key("gathering").name("同案犯聚集").count(0L).build();

        if (ObjectUtil.isNotNull(beginDate) && ObjectUtil.isNotNull(endDate)) {
            // 查询预警数据
            Cre_warningPageInfo queryPageInfo = new Cre_warningPageInfo();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            queryPageInfo.setF_rectime(format.format(beginDate));
            queryPageInfo.setF_rectime_01(format.format(endDate));
            queryPageInfo.setF_deptid(pageInfo.getF_deptid());
//            List<Cre_warning> allWarningList = creWarningDaoCustom.findByTimeAndDeptid(queryPageInfo);
            List<Cre_warning> allWarningList = creWarningDao.findByTimeAndDeptid(queryPageInfo);
            // 进行统计
            if (CollectionUtil.isNotEmpty(allWarningList)) {
                Map<Integer, List<Cre_warning>> allWarningMap = allWarningList.stream().filter(el -> ObjectUtil.isNotNull(el.getType()))
                        .collect(Collectors.groupingBy(Cre_warning::getType));
                if (ObjectUtil.isNotNull(allWarningMap)) {
                    for (Integer type : allWarningMap.keySet()) {
                        Long count = allWarningMap.get(type).stream().count();
                        switch (type) {
                            case Tp_crc_warn.CROSS:
                                countCross.setCount(count);
                                break;
                            case Tp_crc_warn.SEPARATION:
                                countSeparation.setCount(count);
                                break;
                            case Tp_crc_warn.LOCATIONS:
                                countLocations.setCount(count);
                                break;
                            case Tp_crc_warn.LURKS:
                                countLurks.setCount(count);
                                break;
                        }
                    }
                }
            }
        }

//        return Arrays.asList(countCross, countSeparation, countLocations, countLurks, countGathering);
        return Arrays.asList(countCross, countSeparation, countLocations, countLurks);
    }

    @Override
    public PageDataResponse countWarningInfoByCondition(CorrectCountPageInfo pageInfo) throws BusinessException {
        // 查询预警数据
        List<WarningDetails> result = new ArrayList<>();
        Cre_warningPageInfo queryPageInfo = new Cre_warningPageInfo();
        if (ObjectUtil.isNotNull(pageInfo.getWarnType())) {
            List<Integer> warnTypeList = new ArrayList<>();
            warnTypeList.add(pageInfo.getWarnType());
            queryPageInfo.setF_type(warnTypeList);
        }
        if (StringUtils.isNotEmpty(pageInfo.getQueryKey())) {
            queryPageInfo.setF_pername(pageInfo.getQueryKey());
        }
        if (ObjectUtil.isNotNull(pageInfo.getPageNumber())) {
            queryPageInfo.setPageNumber(pageInfo.getPageNumber());
        }
        if (ObjectUtil.isNotNull(pageInfo.getPageSize())) {
            queryPageInfo.setPageSize(pageInfo.getPageSize());
        }
        if (ObjectUtil.isNotNull(pageInfo.getF_deptid())) {
            queryPageInfo.setF_deptid(pageInfo.getF_deptid());
        }
        if (ObjectUtil.isNotNull(pageInfo.getWarnStatus())) {
            switch (pageInfo.getWarnStatus()) {
                case 1:
                    queryPageInfo.setF_status(Arrays.asList(St_work.DONE));
                    break;
                case 2:
                case 3:
                    queryPageInfo.setF_status(Arrays.asList(St_work.UNDO, St_work.DOING));
                    break;
            }
        }
//        if (ObjectUtil.isNotNull(pageInfo.getWarnTime())) {
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//            Calendar calendar = Calendar.getInstance();
//            Date currentDate = calendar.getTime();
//            calendar.add(Calendar.DAY_OF_MONTH, -pageInfo.getWarnTime());
//            Date endTime = calendar.getTime();
//            // 起始时间（多少天以前）
//            queryPageInfo.setF_rectime(dateFormat.format(endTime));
//            // 结束时间（当前时间）
//            queryPageInfo.setF_rectime_01(dateFormat.format(currentDate));
//        }
        if (ObjectUtil.isNotNull(pageInfo.getStartTime()) && ObjectUtil.isNotNull(pageInfo.getEndTime())) {
            if (pageInfo.getStartTime().compareTo(pageInfo.getEndTime()) > 0) {
                log.error("选择的开始时间不能在结束时间之后！startTime:{}, endTime:{}", pageInfo.getStartTime(), pageInfo.getEndTime());
                throw new BusinessException("选择的开始时间不能在结束时间之后！");
            }
            LocalDateTime startTime = pageInfo.getStartTime().toInstant().atZone(ZoneId.of("GMT+8")).toLocalDate().atTime(LocalTime.MIN);
            LocalDateTime endTime = pageInfo.getEndTime().toInstant().atZone(ZoneId.of("GMT+8")).toLocalDate().atTime(LocalTime.MAX);
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            queryPageInfo.setF_rectime(startTime.format(dtf));
            queryPageInfo.setF_rectime_01(endTime.format(dtf));
        }


        Page<Cre_warning> allWarningPage = creWarningDao.queryPage(queryPageInfo);

        if (ObjectUtil.isNull(allWarningPage) || ObjectUtil.isEmpty(allWarningPage.getContent())) {
            return null;
        }

        for (Cre_warning warning : allWarningPage) {
            if (ObjectUtil.isNull(warning)) continue;
            warning.geneText();
            initMobileAddr(warning);
            Crc_person personInfo = crcPersonDao.findDeptById(warning.getPerid());
            personInfo.geneText();
            try {
                warning.setPername(smService.encrypt(warning.getPername()));
                warning.setDescribe(smService.encrypt(warning.getDescribe()));
                personInfo.setPhone(smService.encrypt(personInfo.getPhone()));
                personInfo.setName(smService.encrypt(personInfo.getName()));
            } catch (Exception e) {
                throw new BusinessException("信息加密有误");
            }
            WarningDetails warningDetail = new WarningDetails(warning);
            warningDetail.setPersonInfo(personInfo);
            result.add(warningDetail);

        }


        /*allWarningPage.getContent().stream().filter(e -> ObjectUtil.isNotNull(e)).forEach(el -> {
            el.geneText();
            initMobileAddr(el);
            WarningDetails warningDetail = new WarningDetails(el);
            result.add(warningDetail);
        });
        // 查询人员数据
        List<String> personIds = allWarningPage.getContent().stream().map(Cre_warning::getPerid).distinct().collect(Collectors.toList());
        List<Crc_person> personList = crc_personService.findByPersonIds(personIds);
        for (Crc_person person : personList) {
            Map<String, Ha_attachment> haAttachmentsByIds = ha_attachmentService.getHa_attachmentsByIds(Arrays.asList(person.getAvatar()));
            if (ObjectUtil.isNull(haAttachmentsByIds)) {
                continue;
            }
            Ha_attachment haAttachment = haAttachmentsByIds.get(person.getAvatar());
            person.setAvatarUrl(haAttachment.getPath());
        }
        // 进行赋值
        if (CollectionUtil.isNotEmpty(result) && CollectionUtil.isNotEmpty(personList)) {
            result.stream().forEach(el -> {
                Crc_person personInfo = personList.stream().filter(item -> item.getId().equals(el.getPerid())).findAny().orElse(null);
                if (ObjectUtil.isNotNull(personInfo)) {
                    personInfo.geneText();
                    personInfo.setDeptname(personInfo.getDeptid());
                    try {
                        personInfo.setPhone(smService.encrypt(personInfo.getPhone()));
                        personInfo.setName(smService.encrypt(personInfo.getName()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    el.setPersonInfo(personInfo);
                }
            });
        }*/


        PageDataResponse pageResult = new PageDataResponse(result, allWarningPage.getTotalElements(),
                allWarningPage.getSize(), pageInfo.getPageNumber() <= 1 ? 1 : pageInfo.getPageNumber());
        return pageResult;
    }


    @Override
    public List<MarkPointVO> getPersonMarkPoint(MarkPointPageInfo pageInfo) {
        // 查询公安数据
        Cre_record_gaPageInfo queryParam = new Cre_record_gaPageInfo();
        if (StringUtils.isNotEmpty(pageInfo.getStartDate()) && StringUtils.isNotEmpty(pageInfo.getEndDate())) {
            queryParam.setF_rectime(pageInfo.getStartDate());
            queryParam.setF_rectime_01(pageInfo.getEndDate());
        }
        List<Cre_record_ga> record_gaList = cre_record_gaService.findByConditon(queryParam);
        if (CollectionUtil.isNotEmpty(record_gaList)) {
            List<MarkPointVO> result = new ArrayList<>();
            // 进行数据分组和排序
            Map<String, List<Cre_record_ga>> recordMap = record_gaList.stream().filter(el -> ObjectUtil.isNotNull(el.getPerid()) && ObjectUtil.isNotNull(el.getRectime()))
                    .collect(Collectors.groupingBy(Cre_record_ga::getPerid));
            // 进行分类
            for (String key : recordMap.keySet()) {
                List<Cre_record_ga> recordList = recordMap.get(key);
                recordList = recordList.stream().sorted(Comparator.comparing(Cre_record_ga::getRectime).reversed()).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(recordList)) {
                    Cre_record_ga cre_record_ga = recordList.get(0);
                    result.add(MarkPointVO.builder().id(cre_record_ga.getPerid()).gaid(cre_record_ga.getId()).rectime(cre_record_ga.getRectime())
                            .lat(cre_record_ga.getLatcamera().toString()).lng(cre_record_ga.getLngcamera().toString()).build());
                }
            }
            return result;
        }
        return Collections.emptyList();
    }


    @Override
    public List<MarkPointVO> getPersonMoveTrack(Integer gaId, Integer timeScope) {
        Cre_record_ga cre_record_ga = cre_record_gaService.getById(gaId);
        if (ObjectUtil.isNotNull(cre_record_ga)) {
            List<MarkPointVO> result = new ArrayList<>();
            Date rectime = cre_record_ga.getRectime();
            LocalDateTime localDateTime = rectime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            // 获取数据范围
            LocalDateTime startTime = localDateTime.plusMinutes(-timeScope.longValue());
            LocalDateTime endTime = localDateTime.plusMinutes(timeScope.intValue());
            Cre_record_gaPageInfo pageInfo = new Cre_record_gaPageInfo();
            pageInfo.setF_perid(cre_record_ga.getPerid());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            pageInfo.setF_rectime(startTime.format(formatter));
            pageInfo.setF_rectime_01(endTime.format(formatter));
            log.info("startTime:{},endTime:{}", startTime, endTime);
//            List<Cre_record_ga> record_gaList = cre_record_gaService.findByConditon(pageInfo);
            List<MarkPointVO> actionTrack = cre_record_gaService.getActionTrack(pageInfo);

//            if (CollectionUtil.isNotEmpty(record_gaList)) {
//                record_gaList = record_gaList.stream().sorted(Comparator.comparing(Cre_record_ga::getRectime)).collect(Collectors.toList());
//                record_gaList.stream().forEach(item -> {
//                    result.add(MarkPointVO.builder().id(item.getPerid()).traceId(NanoIdUtils.randomNanoId()).gaid(item.getId()).rectime(item.getRectime())
//                            .lat(item.getLatcamera().toString()).lng(item.getLngcamera().toString()).build());
//                });
//            }
            return actionTrack;
        }
        return Collections.emptyList();
    }

    @Override
    public List<Cre_record_ga> getCreRecordGaList(Integer gaId, Integer timeScope) {
        Cre_record_ga cre_record_ga = cre_record_gaService.getById(gaId);
        if (ObjectUtil.isNotNull(cre_record_ga)) {
            List<MarkPointVO> result = new ArrayList<>();
            Date rectime = cre_record_ga.getRectime();
            LocalDateTime localDateTime = rectime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            // 获取数据范围
            LocalDateTime startTime = localDateTime.plusMinutes(-timeScope.longValue());
            LocalDateTime endTime = localDateTime.plusMinutes(timeScope.intValue());
            Cre_record_gaPageInfo pageInfo = new Cre_record_gaPageInfo();
            pageInfo.setF_perid(cre_record_ga.getPerid());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            pageInfo.setF_rectime(startTime.format(formatter));
            pageInfo.setF_rectime_01(endTime.format(formatter));
            List<Cre_record_ga> record_gaList = cre_record_gaService.findByConditon(pageInfo);
            return record_gaList;
        }
        return Collections.emptyList();
    }

    @Override
    public List<MarkPointVO> getCameraMarkPoint() {
        List<Crc_camera> cameraList = crc_cameraService.findAll();
        if (CollectionUtil.isNotEmpty(cameraList)) {
            List<MarkPointVO> result = new ArrayList<>();
            cameraList.stream().forEach(el -> {
                result.add(MarkPointVO.builder().id(el.getId()).lat(el.getLat().toString()).lng(el.getLng().toString()).build());
            });
            return result;
        }
        return Collections.emptyList();
    }

    @Override
    public CameraInfoVO getCameraInfoDetail(CameraPageInfo cameraPageInfo) {
        Crc_camera crc_camera = crc_cameraService.getById(cameraPageInfo.getCameraId());
        if (ObjectUtil.isNotNull(crc_camera)) {
            // 查询当前点的拍摄的公安数据
            Cre_record_gaPageInfo record_gaPageInfo = new Cre_record_gaPageInfo();
            Cre_warningPageInfo warningPageInfo = new Cre_warningPageInfo();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            if (ObjectUtil.isNotNull(cameraPageInfo.getStartDate()) && ObjectUtil.isNotNull(cameraPageInfo.getEndDate())) {
                record_gaPageInfo.setF_rectime(dateFormat.format(cameraPageInfo.getStartDate()) + " 00:00:00");
                record_gaPageInfo.setF_rectime_01(dateFormat.format(cameraPageInfo.getEndDate()) + " 23:59:59");
                warningPageInfo.setF_rectime(dateFormat.format(cameraPageInfo.getStartDate()) + " 00:00:00");
                warningPageInfo.setF_rectime_01(dateFormat.format(cameraPageInfo.getEndDate()) + " 23:59:59");
            }
            Long recentShotNum = cre_record_gaService.countCameraShotTotal(crc_camera, record_gaPageInfo);
            Long personNum = cre_record_gaService.countCameraPersonTotal(crc_camera, record_gaPageInfo);
            Long warnNum = cre_warningService.countCameraWarnTotal(crc_camera, warningPageInfo);
            warningPageInfo.setF_status(Arrays.asList(String.valueOf(St_work.DONE)));
            Long dealDoneNum = creWarningDao.countCarmeraDealTotal(crc_camera.getLatlng(), St_work.DONE);
            CameraInfoVO result = CameraInfoVO.builder()
                    .recentShotNum(recentShotNum)
                    .personNum(personNum)
                    .warningNum(warnNum)
                    .dealDoneNum(dealDoneNum == null ? 0L : dealDoneNum)
                    .build();
            BeanUtil.copyProperties(crc_camera, result);
            return result;
        }
        return null;
    }

    @Override
    public PageDataResponse getMonitorCondition(CorrectCountPageInfo pageInfo) {
        // 获取选中日期当天的开始和结束时间
        Instant instant = pageInfo.getMonitorTime().toInstant();
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("GMT+8"));
        LocalDate localDate = zonedDateTime.toLocalDate();
        LocalDateTime startDateTime = localDate.atStartOfDay();
        LocalDateTime endDateTime = localDate.atTime(23, 59, 59);
        String startDateTimeStr = startDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String endDateTimeStr = endDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        List<RecordGaDetails> result = new ArrayList<>();
        Cre_record_gaPageInfo queryPageInfo = new Cre_record_gaPageInfo();
        if (ObjectUtil.isNotNull(pageInfo.getPageNumber())) {
            queryPageInfo.setPageNumber(pageInfo.getPageNumber());
        }
        if (ObjectUtil.isNotNull(pageInfo.getPageSize())) {
            queryPageInfo.setPageSize(pageInfo.getPageSize());
        }
        queryPageInfo.setF_rectime(startDateTimeStr);
        queryPageInfo.setF_rectime_01(endDateTimeStr);
        Page<Cre_record_ga> gas = cre_record_gaService.getDayMonitor(queryPageInfo);
        if (CollectionUtil.isEmpty(gas)) {
            return null;
        }
        for (Cre_record_ga ga : gas.getContent()) {
            Crc_person personInfo = crcPersonDao.findPersonById(ga.getPerid());
            try {
                personInfo.setPhone(smService.encrypt(personInfo.getPhone()));
                personInfo.setName(smService.encrypt(personInfo.getName()));
            } catch (Exception e) {
                log.error("加密失败:【{}】", e.getMessage());
            }
            List<PhotoVO> photoVOList = this.getWarningPhotoMap(ga.getId(), 100);
            RecordGaDetails gaDetails = RecordGaDetails.builder()
                    .recordGaInfo(ga)
                    .personInfo(personInfo)
                    .photoVOList(photoVOList)
                    .build();
            result.add(gaDetails);
        }
        PageDataResponse response = new PageDataResponse(result, gas.getTotalElements(),
                pageInfo.getPageSize(), pageInfo.getPageNumber() <= 1 ? 1 : pageInfo.getPageNumber());
        return response;
    }

    /**
     * 获取监控列表
     *
     * @param pageInfo
     * @return
     */
    @Override
    public PageDataResponse getMonitoringList(CorrectCountPageInfo pageInfo) throws Exception {
//    public List<MonitoringVO> getMonitoringList(CorrectCountPageInfo pageInfo) {
        // 获取选中日期当天的开始和结束时间
        Instant instant = pageInfo.getMonitorTime().toInstant();
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("GMT+8"));
        LocalDate localDate = zonedDateTime.toLocalDate();
        LocalDateTime startDateTime = localDate.atStartOfDay();
        LocalDateTime endDateTime = localDate.atTime(23, 59, 59);
        String startDateTimeStr = startDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String endDateTimeStr = endDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        Cre_record_gaPageInfo queryPageInfo = new Cre_record_gaPageInfo();
        queryPageInfo.setF_rectime(startDateTimeStr);
        queryPageInfo.setF_rectime_01(endDateTimeStr);

        // 查询当天抓拍人员信息
        List<MonitoringVO> monitoringVO = cre_record_gaService.getMonitoringList(queryPageInfo);

        if (CollectionUtil.isEmpty(monitoringVO)) {
            return null;
        }

        Map<String, List<MonitoringVO>> monitoringMap = monitoringVO.stream()
                .collect(Collectors.groupingBy(MonitoringVO::getPerid));

        // 创建一个新的Map，用于存储排序后的结果
        Map<String, List<MonitoringVO>> sortedMap = new LinkedHashMap<>();
        // 遍历原始Map，对每个List<MonitoringVO>进行排序
        monitoringMap.forEach((perid, list) -> {
            List<MonitoringVO> sortedList = list.stream()
                    .sorted(Comparator.comparing(MonitoringVO::getRectime))
                    .collect(Collectors.toList());
            sortedMap.put(perid, sortedList);
        });

        List<MonitoringVO> volist = new ArrayList<>();
        sortedMap.forEach((perid, monitoringVOS) -> {
            for (int i = 0; i < monitoringVOS.size(); i++) {
                MonitoringVO monitoring = monitoringVOS.get(i);
                if (monitoringVOS.size() == 1) {
                    continue;
                }
                // 获取两个小时后的时间
                LocalDateTime twoHoursLater = monitoring.getRectime()
                        .toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()
                        .plusHours(2);
                Date endDate = Date.from(twoHoursLater.atZone(ZoneId.systemDefault()).toInstant());

                // 获取列表其他时间，大于两个小时以后的时间则原数据添加到结果中，小于或等于则属于原数据范围内
                for (int j = 0; j < monitoringVOS.size(); j++) {
                    Date rectime = monitoringVOS.get(j).getRectime();
                    int diff = rectime.compareTo(endDate);
                    if (diff < 0) {
                        monitoringVOS.remove(j);
                    }
                }
            }
            volist.addAll(monitoringVOS);
        });

        List<MonitoringVO> result = volist.stream()
                .sorted(Comparator.comparing(MonitoringVO::getRectime))
                .skip((long) (pageInfo.getPageNumber() - 1) * pageInfo.getPageSize())
                .limit(pageInfo.getPageSize())
                .collect(Collectors.toList());

        for (MonitoringVO vo : result) {
            vo.setName(smService.encrypt(vo.getName()));
            vo.setPhone(smService.encrypt(vo.getPhone()));
        }


        PageDataResponse response = new PageDataResponse(result, Long.valueOf(volist.size()),
                pageInfo.getPageSize(), pageInfo.getPageNumber() <= 1 ? 1 : pageInfo.getPageNumber());

        return response;
    }
}
